package services

import (
	"context"

	"go.uber.org/zap"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"

	"gitee.com/monkeyPP/happy-mall/api/userservice/proto"
	"gitee.com/monkeyPP/happy-mall/services/userservice/internal/application"
	"gitee.com/monkeyPP/happy-mall/services/userservice/internal/domain/entity"
)

// UserServiceServer 用户服务 gRPC 实现
type UserServiceServer struct {
	userApp application.UserApp
	logger  *zap.Logger
	proto.UnimplementedUserServiceServer
}

// NewUserServiceServer 创建新的用户服务服务器
func NewUserServiceServer(userApp application.UserApp, logger *zap.Logger) *UserServiceServer {
	return &UserServiceServer{
		userApp: userApp,
		logger:  logger,
	}
}

// RegisterServices 实现 ServiceRegistrar 接口
func (s *UserServiceServer) RegisterServices(server *grpc.Server) {
	proto.RegisterUserServiceServer(server, s)
	s.logger.Info("user service registered")
}

// GetUser 实现获取用户方法
func (s *UserServiceServer) GetUser(ctx context.Context, req *proto.GetUserRequest) (*proto.UserResponse, error) {
	s.logger.Info("GetUser called",
		zap.String("id", req.Id),
		zap.String("name", req.Name))

	// 参数验证
	if req.Id == "" && req.Name == "" {
		return nil, status.Error(codes.InvalidArgument, "id or name is required")
	}

	// TODO: 这里需要根据实际业务逻辑调用 userApp 的方法
	// 当前 userApp 只有 Register 方法，需要添加 GetUser 方法

	// 临时实现，返回模拟数据
	return &proto.UserResponse{
		Id:       req.Id,
		Name:     req.Name,
		Password: "masked", // 不返回真实密码
	}, nil
}

// AddUser 实现添加用户方法
func (s *UserServiceServer) AddUser(ctx context.Context, req *proto.AddUserRequest) (*proto.UserResponse, error) {
	s.logger.Info("AddUser called", zap.String("name", req.Name))

	// 参数验证
	if req.Name == "" || req.Password == "" {
		return nil, status.Error(codes.InvalidArgument, "name and password are required")
	}

	// 创建用户实体
	userEntity := &entity.User{
		Name:     req.Name,
		Password: req.Password,
	}

	// 调用业务逻辑层
	user, err := s.userApp.Register(ctx, userEntity)
	if err != nil {
		s.logger.Error("failed to register user", zap.Error(err))
		return nil, status.Error(codes.Internal, "failed to register user")
	}

	return &proto.UserResponse{
		Id:       user.ID,
		Name:     user.Name,
		Password: "masked", // 不返回真实密码
	}, nil
}
